#pragma once


#include "Comm.hpp"

class Channel
{
private:
    using EventCallback = std::function<void()>;
    using OperatorForPoller = std::function<void()>;

public:
    Channel(int fd) : _fd(fd), _events(0), _revents(0) {}

    int GetFD() { return _fd; }

    uint32_t GetEvents() { return _events; }

    void SetRevent(uint32_t events) { _revents = events; }

    void SetReadCallback(const EventCallback &cb) { _read_callback = cb; }

    void SetWriteCallback(const EventCallback &cb) { _write_callback = cb; }

    void SetErrorCallback(const EventCallback &cb) { _error_callback = cb; }

    void SetDisconnCallback(const EventCallback &cb) { _disconn_callback = cb; }

    void SetElseCallback(const EventCallback &cb) { _else_callback = cb; }

    bool IsReadAbleCtl() { return (_events & EPOLLIN); }

    bool IsWriteAbleCtl() { return (_events & EPOLLOUT); }

    // 启动读事件监控
    void EnableRead() { _events |= EPOLLIN; Update(); }

    // 启动写事件监控
    void EnableWrite() { _events |= EPOLLOUT; Update(); }

    void DisableRead() { _events &= ~EPOLLIN; Update(); }

    void DisableWrite() { _events &= ~EPOLLOUT; Update(); }

    void DisableAll() { _events = 0; Update(); }

    // 移除该描述符的所有监控
    void Remove() { _remove(); }

    void Update() { _update(); }

    void RegisterOperator(const OperatorForPoller& update, const OperatorForPoller& remove)
    {
        _update = update;
        _remove = remove;
    }

    // 一但连接触发事件，就调用该函数处理事件
    void HandleEvent()
    {
        if ((_revents & EPOLLIN) || (_revents & EPOLLRDHUP) || (_revents & EPOLLPRI))
        {
            if (_read_callback) _read_callback();
        }

        if (_revents & EPOLLOUT)
        {
            if (_write_callback) _write_callback();
        }
        else if (_revents & EPOLLERR)
        {
            if (_error_callback) _error_callback();
        }
        else if (_revents & EPOLLHUP)
        {
            if (_disconn_callback) _disconn_callback();
        }
        if (_else_callback) _else_callback();
    }

private:
    int _fd;
    uint32_t _events;                    // 当前需要监控的事件
    uint32_t _revents;                   // 当前连接触发的事件

    EventCallback _read_callback;        // 可读事件被触发的回调函数
    EventCallback _write_callback;       // 可写事件被触发的回调函数
    EventCallback _error_callback;       // 错误事件被触发的回调函数
    EventCallback _disconn_callback;     // 断开连接事件被触发的回调函数
    EventCallback _else_callback;        // 其他事件被触发的回调函数
    
    OperatorForPoller _update;           // 将事件的更新结果响应给 Poller 模块进行回调
    OperatorForPoller _remove;           // 该 fd 需要被移除的结果也需要响应给 Poller 模块进行回调
};